.TITLE MKDRV .IDENT /02/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 02 ; ; J. REED 6-OCT-78 ; ; MODIFIED BY: ; ; J.E.POLLACK 18-JUL-79 ; ; EP011 -- ADD CLEAR MEMORY FUNCTION ; ; B. S. MCCARTHY ; ; VARIOUS BUG FIXES THROUGHOUT HISTORY ; ; ; ; MKA11 MEMORY DRIVER ; ; ; THE MKA11 MEMORY DRIVER IS THE INTERFACE BETWEEN HRC AND THE ; MEMORY CSRS. THE ONLY TASK THAT MAY ACCESS THIS DRVIER IS HRC. ; ; ; MACRO LIBRARY CALLS ; .MCALL HWDDF$,PKTDF$,MKDEF$,UCBDF$ HWDDF$ PKTDF$ MKDEF$ UCBDF$ ; DEFINE UCB OFFSETS ; ; BIT ASSIGNMENTS ; BIT0 = 1 BIT1 = 2 BIT2 = 4 BIT3 = 10 BIT4 = 20 BIT5 = 40 BIT6 = 100 BIT7 = 200 BIT8 = 400 BIT9 = 1000 BIT10 = 2000 BIT11 = 4000 BIT12 = 10000 BIT13 = 20000 BIT14 = 40000 BIT15 = 100000 ; ; CSR OFFSETS ; CSR1 = 0 ; CSR2 = 2 ; SECOND CSR CONTROL WORD ; ; BIT DEFINITIONS FOR MK11 CSRS ; PROG = BIT10 ; BOX CONTROL 1 => PROGRAMMMABLE, 0 => MANUAL ECC = BIT1 ; ECC DISABLE 1 => SINGLE BIT ERRORS DETECTABLE SIZ = BIT3 ; SEIND = BIT4 ; SBE SEEN 1=> SINGLE BIT ERROR SEEN CONSEL = BIT9 ; IIN = BIT11 ; INTERNAL INTERLEAVE OGMSK = PROG!777 ; BAS1 = EPT ; BAS2 = OGMSK!PROG ; INMSK = BIT12!BIT13!BIT14 ; EXTERNAL INTERLEAVE MASK PROPTR = BIT3 ; PROTECTION POINTER ; ; OFFSETS INTO THE MK UCB PRIVATE DATA ; U.KCTR = U.CNT+2 ; COUNTER OF KRBS SCANNED FOR THE CURRENT BOX U.STAD = U.CNT+4 ; POINTER TO STATUS WORD OF USER PARAMETER ; BUFFER U.PWRV = U.CNT+6 ; POWER FAIL VECTOR FOR INTERNAL ROUTINES U.CSAV = U.CNT+10 ; START OF 8-WORD CSR SAVE AREA FOR CSR ; CONTENTS OF ALL PORTS OF THIS BOX. ; ; ; MISC. PARAMETERS ; GRANUL = +10. ; GRANULARITY OF MEMORY ; ONE UNIT OF BASE ADDRESS = 2**GRANUL BYTES GRASHF = 2000 ; 1**GRANUL ; ; FUNCTION JUMP TABLE ; FCNLST: .BYTE IO.ORG/400 ; SET/READ BOX ORIGIN .BYTE IO.INT/400 ; SET/READ INTERLEAVE .BYTE IO.IIN/400 ; READ INTERNAL INTERLEAVE .BYTE IO.PRG/400 ; SET/READ PROGRAMMABLE .BYTE IO.ERR/400 ; READ ERROR STATUS .BYTE IO.GRN/400 ; READ GRUNULARITY .BYTE IO.SIZ/400 ; READ BOX SIZE .BYTE IO.RSA/400 ; READ ERROR INFORMATION .BYTE IO.CST/400 ; .BYTE IO.MSK/400 ; SET DIAGONSTIC MASK .BYTE IO.CLM/400 ; CLEAR MEMORY .BYTE 0 ; TERMINATOR ; ; SERVICE ROUTINE ADDRESSES ; FCNJMP: .WORD IOORG ; SERVICE ROUTINE ADDRESSES FOR THE .WORD IOINT ; ABOVE FUNCTIONS CODES .WORD IOIIN ; .WORD IOPRG ; .WORD IOERR ; .WORD IOGRN ; .WORD IOSIZ ; .WORD IORSA ; .WORD IOCST ; .WORD IOMSK ; .WORD IOCLM ; ; ; ; ERROR CODE STORAGE BUFFER ; ; ECOD1: .WORD 0 ; STATUS RETURN VALUES FOR I/O OPERATION ECOD2: .WORD 0 ; ; ; ; DEVICE DISPATCH TABLE ; ; DDT$ MK,M$$K11,,,,T ; ; ; ; IN ADDITION TO THE NORMAL $GTPKT OPERATION, A CALL WILL BE MADE TO ; THE ROUTINE $CFORK. THIS ROUTINE WILL DETERMINE THE PROCESSOR ; THAT IS CURRENTLY EXECUTING THIS ROUTINE AND COMPARE IT WITH ; THE ONE INDICATED IN THE SCB AT S.URM. IF THEY ARE THE SAME ; THEN A RETURN IS EXECUTED AND PROCESSING CONTINUES. IF THEY ARE ; DIFFERENT THEN $CFORK SAVES THE CONTEXT IN THE FORK BLOCK AND ; ENTERS THIS REQUEST INTO THE FORK QUE FOR THE PROPER PROCESSOR. ; CONTROL IS RETURNED TO THE CALLERS CALLER WITH THE CARRY BIT SET. ; IN THIS CASE CONTROL WILL RETURN TO THE DRIVER WHICH WILL RETURN ; TO THE EXEC. ; ; .PAGE ; ; ; ; DRIVER INITALIZE ENTRY POINT ; .ENABLE LSB MKINI: GTPKT$ MK,M$$K11,,,T ; ; ; REGISTER SUMMARY: ; ; R0 = UNDEFINED ; R1 = ADDRESS OF I/O PACKET ; R2 = PHYICAL UNIT NUMBER ON CONTROLLER ; R3 = CONTROLLER INDEX IN LIST OF ALL SIMILAR CONTROLLERS IN SYSTEM ; R4 = ADDRESS OF SCB ; R5 = ADDRESS OF UCB ; ; ; ; I/O PACKET FORMAT: ; ; ; I.LNK: I/O QUEUE THREAD WORD ; I.PRI: REQUEST PRIORITY ; I.EFN: EVENT FLAG NUMBER ; I.TCB: ADDRESS OF TCB OF REQUESTOR TASK ; I.LN2: ADRESS OF LUN2 WORD IN HEADER OF REQUESTOR TASK ; I.UCB: ADDRESS OF UCB ; I.FCN: I/O FUNCTION CODE ; I.IOSB: VIRTUAL ADDRESS OF I/O STATUS BLOCK ; +2: RELOCATION BIAS OF I/O STATUS BLOCK ; +4: DISPLACEMENT OF I/O STATUS BLOCK (RELATIVE TO APR6) ; I.AST: VIRTUAL ADDRESS OF AST SERVICE ROUTINE ; I.PRM: RELOCATION BIAS OF FIRST I/O BUFFER ; +2: DISPLACMENT RELATIVE TO APR6 ; +4: BUFFER SIZE IN BYTES ; ; ; ; ; ; ; ; ; IN THE USER BUFFER. ; ; CLR U.KCTR(R5) ; CLEAR THE PORT POINTER JUST IN CASE MOV U.BUF+2(R5),-(SP) ; SAVE THE PRESENT BUFFER ADDRESS MOV (SP),U.STAD(R5) ; SAVE THE INITIAL BUFFER ADDRESS ADD #10,U.STAD(R5) ; AND ADD THE OFFSET TO THE STATUS WORD MOV U.STAD(R5),U.BUF+2(R5) ; SET UP THE USER BUFFER STATUS WORD MOV #IS.SUC,-(SP) ; INDICATE SUCCESS TO START WITH MOV (SP),ECOD1 ; INITALIZE FOR SUCCESS CLR ECOD2 ; CALL $PTWRD ; AND PUT IT INTO THE BUFFER MOV (SP)+,U.BUF+2(R5) ; RESTORE THE BUFFER ADDRESS ; ; ; ; THEN WE EXIT WITH AN ERROR. ; ; MOV I.TCB(R1),R3 ; GET THE ADDRESS OF THE TASK CONTROL ; BLOCK INTO R3 BIT #T3.PRV,T.ST3(R3); TEST THE PRIVILEGE BIT OF THE THIRD ; STATUS WORD IN THE TCB BEQ 3$ ; IF EQUAL THEN THE TASK IS NOT ; PRIVILEGED AND WE RETURN AN ERROR CMP R3,$HRCPT ; WAS IT HRC... ? BEQ 5$ ; YES -- PROCEED 3$: MOV #IE.PRI&377,-(SP) ; ELSE WE MOVE THE ERROR ONTO THE STACK JMP ERROR ; AND REPORT THE ERROR ; ; SELECT SERVICE ROUTINE FROM FUNCTION CODE ; 5$: MOV #FCNLST,R0 ; POINT TO VECTOR OF FUNCTION CODES 6$: CMPB I.FCN+1(R1),(R0) ; IS THIS THE REQUESTED FUNCTION? BEQ 7$ ; BR IF YES TSTB (R0)+ ; HAVE WE SEEN THE TERMINATOR YET? BNE 6$ ; BR IF NOT MOV #IE.IFC&377,-(SP) ; SET ILLEGAL FUNCTION CODE JMP ERROR ; TAKE ERROR RETURN 7$: SUB #FCNLST,R0 ; OBTAIN OFFSET IN FUNCTION LIST ASL R0 ; CONVERT TO WORD OFFSET MOV FCNJMP(R0),U.PWRV(R5) ; SAVE THE FUNCTION ROUTINE IN THE ; POWERFAIL RECOVERY BUFFER JMP @FCNJMP(R0) ; AND GO TO SERVICE ROUTINE ; .PAGE ; STARTING ADDRESS OF BOX: ; ; IF MS.SET BIT IS SET THIS FUNCTION WILL CHANGE ALL OF THE PORTS ; ON THIS BOX TO THE STARTING ADDRESS SUPPLIED IN THE FIRST WORD ; OF THE USER BUFFER. IF ANY OF THE PORTS ARE IN THE 'FORCED PANEL' ; MODE SO THAT THEY CANNOT BE PROGRAMMED THE ERROR CODE IE.WLK&377 ; IS RETURNED IN THE IOSB AND NO FURTHER ATTEMPT IS MADE TO CONTINUE ; PROGRAMMING THE REST OF THE PORTS. IF ANY PORT FAILS TO ACCEPT ; THE STARTING ADDRESS BUT INDICATES THAT IT IS PROGRAMMABLE, THE ; ERROR CODE IE.FHE&377 IS RETURNED IN THE IOSB AND NO FURTHER ATTEMPT ; IS MADE TO CONTINUE PROGRAMMING THE STARTING ADDRESSES. ; ; IF MS.SET IS NOT SET THIS FUNCTION WILL REPORT THE STARTING ADDRESSES ; OF ALL OF THE PORTS ON THIS BOX IN THE FIRST FOUR WORDS OF THE ; USER BUFFER. ; ; STATUS IS RETURNED IN THE FIFTH WORD OF THE USER BUFFER. ; ; IOORG: 11$: CALL ROUND ; SET UP ON EACH PROCESSOR 12$: TST U.KCTR(R5) ; ARE WE THRU YET? BEQ 19$ ; IF EQUAL THEN WE ARE CALL RESET ; RESET THE REGISTERS AFTER RETURN FROM FORK BITB #MS.SET,I.FCN(R1) ; IS IT A SET FUNCTION BEQ 16$ ; GIVE HIM THE INFORMATION CALL $GTWRD ; GET THE ADDRESS DESIRED SUB #2,U.BUF+2(R5) ; RESET THE BUFFER ADDRESS SO THAT WE CAN ; GET THE SAME PARAMETER THE NEXT TIME. MOV (SP)+,R0 ; INTO R0 BIC #^C777,R0 ; RESET ALL BUT ADDRESS FIELD BIS #PROG,R0 ; MASK IN THE PROGRAMABLE BIT MOV CSR2(R4),R3 ; GET THE PRESENT STATE OF THE CSR INTO R3 BIC #OGMSK,R3 ; CLEAR OUT THE STARTING ADDRESS BITS BIS R0,R3 ; PUT THE DESIRED STARTING ADDRESS INTO R3 MOV R3,CSR2(R4) ; PUT THE RESULTS INTO THE CSR BIT #PROG,CSR2(R4) ; DID IT TAKE? BNE 13$ ; IF NOT EQUAL THEN YES MOV #IE.WLK&377,-(SP) ; PUSH THE ERROR CODE ONTO THE STACK CALL STATUS ; REPORT THE PRESENT OF A WRITE LOCKED PORT ; TO THE USER IN THE BUFFER STATUS WORD. BR 11$ ; AND GO AROUND AGAIN 13$: CMPB R0,CSR2(R4) ; IS THE CORRECT ADDRESS ASSERTED? BEQ 11$ ; IF EQUAL THEN YES MOV #IE.FHE&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK JMP ERROR ; REPORT THE ERROR 16$: MOV CSR2(R4),-(SP) ; GET THE ADDRESS INTO -(SP) BIC #^C777,(SP) ; RESET ALL BUT ADDRESS FIELD CALL GTURM ; GET THE UNIBUS RUN MASK INTO R3 ASH #4,R3 ; SHIFT MASK TO UPPER 4 BITS BIS R3,(SP) ; THEN SET IT INTO THE RETURN TO THE ; BUFFER. CALL $PTWRD ; PUT THE RESULTS INTO THE BUFFER BR 11$ ; AND GO GET THE NEXT ONE 19$: JMP SUC ; FINISH UP ; ; ; ; EXTERNAL INTERLEAVING ; ; IOINT: 21$: CALL ROUND ; SET UP ON EACH PROCESSOR 22$: TST U.KCTR(R5) ; ARE WE THRU YET? BEQ 29$ ; IF EQUAL THEN WE ARE CALL RESET ; RESET THE REGISTERS AFTER RETURN FROM FORK BITB #MS.SET,I.FCN(R1) ; IS IT A SET FUNCTION BEQ 26$ ; GIVE THE INFORMATION CALL $GTWRD ; GET THE DESIRED INTERLEAVING FUNCTION CODE MOV (SP)+,R0 ; AND GET IT INTO R0 BIT #370,R0 ; IS IT A GOOD CODE? BEQ 23$ ; IF EQUAL THE YES MOV #IE.BAD&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK JMP ERROR ; REPORT THE ERROR 23$: SUB #2,U.BUF+2(R5) ; RESET THE BUFFER ADDRESS TO THE FIRST WORD ; SO THAT WE CAN GET THE FACTOR ON THE NEXT ; PASS ASL R0 ; GET THE INTERLEAVING FUNCTION ASL R0 ; INTO THE RIGHT POSISTION ASL R0 ; FOR ASSERTION ON THE CSR ASL R0 SWAB R0 BIS #PROG,R0 ; MASK IN THE PROGRAMMABLE BIT MOV CSR2(R4),R3 ; GET THE PRESENT STATE OF THE CSR INTO R3 BIC #INMSK,R3 ; CLEAR OUT THE INTERNAL INTERLEAVING BITS BIS R0,R3 ; SET THE INTERLEAVING FACTOR MOV R3,CSR2(R4) ; PUT THE RESULTS INTO THE CSR BIT #PROG,CSR2(R4) ; DID IT TAKE? BNE 24$ ; IF EQUAL THEN IT IS PROGRAMMABLE MOV #IE.WLK&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK CALL STATUS ; REPORT THE EXISTANCE OF A WRITE LOCKED ; PORT IN THE USER BUFFER STATUS WORD BR 21$ ; AND GO AGAIN 24$: CMPB R3,CSR2(R4) ; IS THE CORRECT ADDRESS ASSERTED? BEQ 21$ ; IF EQUAL THEN YES 26$: MOV CSR2(R4),-(SP) ; GET THE CSR WORD 2 ONTO THE STACK BIC #107777,(SP) ; CLEAR OUT THE REST OF THE WORD SWAB (SP) ; GET THE CODE INTO A READABLE FORM ASR (SP) ASR (SP) ASR (SP) ASR (SP) CALL GTURM ; GET THE UNIBUS RUN MASK INTO R3 BIS R3,(SP) ; SET IT INTO THE HIGH BYTE OF THE ; RETURNED WORD CALL $PTWRD ; BUT IT INTO THE BUFFER BR 21$ ; GO TO THE NEXT PROCESSOR 29$: JMP SUC ; FINISH UP ; ; ; INTERNAL INTERLEAVING ; ; IOIIN: 31$: CALL ROUND ; SET UP ON EACH PROCESSOR 32$: TST U.KCTR(R5) ; ARE WE THRU YET? BEQ 39$ ; IF EQUAL THEN WE ARE CALL RESET ; RESET THE REGISTERS AFTER RETURN FROM FORK BITB #MS.SET!MS.CLR,I.FCN(R1) ; IS IT A SET FUNCTION BEQ 36$ ; IF EQUAL THEN NO MOV CSR2(R4),R0 ; GET THE PRESENT CONTENTS OF THE CSR INTO ; R0 BITB #MS.CLR,I.FCN(R1); IS IT A CLEAR? BEQ 34$ ; IF EQUAL THEN NO BIC #IIN,R0 ; CLEAR THE INTERNAL INTERLEAVING BIT MOV R0,CSR2(R4) ; MOV THE IMAGE INTO THE CSR BIT #IIN,CSR2(R4) ; DID IT WORK? BEQ 31$ ; IF EQUAL THEN YES IT WORKED 33$: MOV #IE.FHE&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK JMP ERROR ; REPORT THE ERROR 34$: BIS #IIN,R0 ; SET THE INTERNAL INTERLEAVING BIT MOV R0,CSR2(R4) ; TRY TO PROGRAM THE PORT BIT #IIN,CSR2(R4) ; IS IT SET? BNE 31$ ; IF NOT EQUAL THEN YES AND GO AGAIN 35$: MOV #IE.WLK&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK CALL STATUS ; INDICATE THAT ONE OF THE PORTS CANNOT ; BE INTERLEAVED BR 31$ ; AND GO AGAIN 36$: BIT #IIN,CSR2(R4) ; IS IT SET BEQ 38$ ; IF EQUAL THEN IT IS CLEAR MOV #1,-(SP) ; INDICATE SET 37$: CALL GTURM ; GET THE UNIBUS RUN MASK INTO R3 BIS R3,(SP) ; REPORT IT CALL $PTWRD ; PUT IT INTO THE BUFFER BR 31$ ; GO TO THE NEXT PROCESSOR 38$: MOV #0,-(SP) ; SHOW CLEARED BR 37$ ; GO AGAIN 39$: JMP SUC ; FINISH UP ; ; ; MANUAL-PROGRAMMABLE MODE ; ; IOPRG: 41$: CALL ROUND ; SET UP ON EACH PROCESSOR 42$: TST U.KCTR(R5) ; ARE WE THRU YET? BEQ 49$ ; IF EQUAL THEN WE ARE CALL RESET ; RESET THE REGISTERS AFTER RETURN FROM FORK BITB #MS.SET!MS.CLR,I.FCN(R1) ; IS IT A SET FUNCTION BEQ 46$ ; IF EQUAL NO BITB #MS.CLR,I.FCN(R1); IS IT A CLEAR COMMAND BNE 43$ ; IF NOT EQUAL THEN YES BIS #PROG,CSR2(R4) ; SET THE BANK TO PROGRAMMABLE BIT #PROG,CSR2(R4) ; IS IT SET BNE 41$ ; IF NOT EQUAL THEN YES MOV #IE.WLK&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK CALL STATUS ; INDICATE THAT ONE OF THE PORTS IS ; FORCED TO THE PANEL. BR 41$ ; AND GO AGAIN 43$: BIC #PROG,CSR2(R4) ; SET THE BANK TO MANUAL BIT #PROG,CSR2(R4) ; IS IT CLEARED BEQ 41$ ; IF EQUAL THEN IT IS CLEARED MOV #IE.FHE&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK JMP ERROR ; REPORT THE ERROR 46$: MOV #1,-(SP) ; ASSUME PROGRAMMABLE BIT #PROG,CSR2(R4) ; IS IT SET? BNE 48$ ; IF NOT EQUAL THEN IT IS PROGRAMMABLE MOV CSR2(R4),R2 ; GET THE IMAGE OF THE CSR INTO R2 BIS #PROG,R2 ; SET THE PROGRAMMABILITY BIT MOV R2,CSR2(R4) ; MOVE IT BACK TO THE CSR BIT #PROG,CSR2(R4) ; IS IT FORCED TO THE PANEL? BEQ 47$ ; IF EQUAL THEN IT IS NOT AND WE REPORT THIS ; PORT AS NOT PROGRAMMABLE. BIC #PROG,CSR2(R4) ; PUT IT BAC THE WAY IT WAS BR 48$ ; AND REPORT IT AS PROGRAMMABLE 47$: CLR (SP) ; ELSE INDICATE FORCED TO THE FRONT PANEL 48$: CALL GTURM ; GET THE UNIBUS RUN MASK INTO THE HIGH ; BYTE OF R3 BIS R3,(SP) ; SET IT INTO THE RETURN WORD CALL $PTWRD ; PUT THE RESULTS INTO THE PACKET BR 41$ ; GO TO THE NEXT PROCESSOR 49$: JMP SUC ; FINISH UP ; ; ; ERROR CORRECTION ENABLE-DISABLE ; ; IOERR: CALL GTONE ; GET ONTO THE DESIRED PROCESSOR 52$: CALL RESET ; RESET THE REGISTERS AFTER RETURN FROM FORK BITB #MS.SET!MS.CLR,I.FCN(R1); IS IT A SET FUNCTION? BEQ 55$ ; IF NOT EQUAL THEN REPORT THE STATUS BITB #MS.CLR,I.FCN(R1) ; IS IT A DISABLE REQUEST? BNE 53$ ; IF NOT EQUAL THEN YES BIC #ECC,(R4) ; ELSE CLEAR THE ECC BIT BIT #ECC,(R4) ; IS IT CLEAR? BEQ 59$ ; IF EQUAL THEN IT IS CLEAR MOV #IE.FHE&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK JMP ERROR ; REPORT THE ERROR 53$: BIS #ECC,(R4) ; SET THE ECC BIT BIT #ECC,(R4) ; IS IT SET? BNE 59$ ; IF NOT EQUAL THEN IT IS SET MOV #IE.FHE&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK JMP ERROR ; REPORT THE ERROR 55$: MOV #0,-(SP) ; ASSUME DISABLED BIT #ECC,(R4) ; IS IT ENABLED? BNE 56$ ; IF NOT EQUAL THEN IT IS DISABLED INC (SP) ; ELSE INDICATE ENABLED 56$: CALL $PTWRD ; REPORT SAME 59$: JMP SUC ; FINISH UP ; ; ; GRANULARITY CHECK ; ; IOGRN: MOV #GRASHF,-(SP) ; SET THE GRANULARITY AT 64K BYTES CALL $PTWRD ; PUT IT INTO THE BUFFER JMP SUC2 ; GO HOME ; ; ; BOX SIZE CHECK ; ; IOSIZ: CALL GTONE ; GET ONTO THE DESIRED PROCESSOR 72$: CALL RESET ; RESET THE REGISTERS AFTER RETURN FROM FORK MOV #SIZ,(R4) ; REQUEST THE BOX SIZE MOV (R4),-(SP) ; GET THE SIZE ONTO THE STACK FOR A ; CALL TO $PTWRD BIC #100377,(SP) ; CLEAN UP THE GARBAGE SWAB (SP) ; SET SIZE INTO LOW BYTE CALL $PTWRD ; OUT IT INTO THE BUFFER JMP SUC ; GO HOME ; ; ; GET PARAMETERS ON SINGLE BIT ERROR ; ; IORSA: CALL GTONE ; GET ONTO THE DESIRED PROCESSOR 82$: CALL RESET ; RESET THE REGISTERS AFTER RETURN FROM FORK BIT #SEIND,(R4) ; IS THE SINGLE BIT ERROR INDICATED? BNE 83$ ; IF NOT EQUAL THEN YES MOV #IE.IDS&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK JMP ERROR ; REPORT THE ERROR 83$: MOV (R4),-(SP) ; PUSH THE ARRAY ADDRESS ONTO THE STACK MOV CSR2(R4),R0 ; GET THE STARTING ADDRESS INTO R0 ASRB (SP) ; GET THE ARRAY ADDRESS INTO ASRB (SP) ; THE FORM OF X TIMES 32K ASRB (SP) ; AND THEN WE WILL ASRB (SP) ; CORRECT FOR WHICH SIDE OF THE BIT #CONSEL,R0 ; OF THE BOX. BEQ 84$ ; IF EQUAL THEN IT IS ON THE RIGHT SIDE ; AND WE HAVE THE RIGHT NUMBER ADD #1,(SP) ; ELSE WE ARE ON THE ODD SIDE AND WE MUST ; ADD ONE TO CORRECT. 84$: ADD R0,(SP) ; ADD THE STARTING ADDRESS TO THE RESULTS SWAB (SP) ; NOW WE GET INTO A 32. WORD FACTOR BIC #377,(SP) ; WITHOUT THE GARBAGE ASL (SP) ASL (SP) MOV (SP),R0 ; AND WE SAVE THE RESULTS IN R0 CALL $PTWRD ; THEN WE PUT THE LOWER END OF THE RANGE INTO ; INTO THE FIRST OUTPUT WORD OF THE ARRAY ADD #GRASHF,R0 ; ADD THE GRANULARITY TO THE RESULTS MOV R0,-(SP) ; AND PUT THE RESULTS CALL $PTWRD ; INTO THE SECOND WORD OF THE BUFFER AS THE ; UPPER LIMIT OF THE RANGE JMP SUC ; AND GO HOME ; ; ; SYSTEM STATUS FUNCTION ; ; IOCST: 91$: CALL GTKRB ; GET THE NEXT KRB INTO R3 BEQ 93$ ; IF EQUAL THEN THIS IS THE END OF THE ; KRB TABLE AND WE ARE THRU WITH THIS ; PART OF THE FUNCTION. MOVB K.URM(R3),-(SP) ; PUT THE UNIBUS RUN MAP ONTO THE STACK BIT K.URM(R3),$URMST ; IS THE PROCESSOR ONLINE? BEQ 92$ ; IF EQUAL THEN IT IS OFFLINE AND WE DO NOT ; SET THE SIGN BIT. BISB #200,(SP) ; ESLE IT IS ONLINE AND WE SO INDICATE 92$: CALL $PTBYT ; PUT IT IN THE OUTPUT BUFFER ADD #2,U.KCTR(R5) ; UPDATE THE COUNTER BR 91$ ; AND GO AGAIN 93$: CLR U.KCTR(R5) ; CLEAR THE OFFSET COUNTER MOV U.STAD(R5),U.BUF+2(R5) ; SET THE BUFFER TO THE FIFTH WORD SUB #4,U.BUF+2(R5) ; AND SUBTRACT FOUR SO THAT WE POINT TO THE ; THIRD WORD. 94$: MOV U.DCB(R5),R3 ; GET THE DCB ADDRESS INTO R3 MOV D.MSK(R3),-(SP) ; GET THE FIRST FUNCTION MASK WORD ONTO THE ; STACK CALL $PTWRD ; PUT IT INTO THE BUFFER MOV D.MSK+10(R3),-(SP) ; GET THE SECOND FUNCTION MASK WORD ; ONTO THE STACK CALL $PTWRD ; PUT IT INTO THE BUFFER JMP SUC ; GO HOME ; ; ; ; DIAGNOSTIC MASK FUNCTION ; ; ; IOMSK: CALL GTONE ; GET ONTO THE DESIRED PROCESSOR CALL RESET ; AND GET THE REGISTERS BACK BITB #MS.SET,I.FCN(R1) ; IS THIS A SET FUNCTION BEQ 102$ ; IF EQUAL THEN IT IS A READ ONLY ; FUNCTION CALL $GTWRD ; ELSE WE GET THE #2 WORD OF THE BUFFER MOV (SP)+,(R4) ; AND MOVE IT INTO THE CSR CALL $GTWRD ; AND WE GET THE #3 WORD OF THE BUFFER MOV (SP)+,CSR2(R4) ; AND MOVE IT INTO THE CSR 102$: MOV (R4),-(SP) ; PUSH THE FIRST WORD OF THE CSR ONTO THE ; STACK CALL $PTWRD ; AND PUT IT INTO THE BUFFER MOV CSR2(R4),-(SP) ; AND THEN THE SECOND WORD CALL $PTWRD ; INTO THE BUFFER JMP SUC ; THEN EXIT WITH STATUS JMP SNAP ; AND END WITH THE SNAPSHOT ROUTINE. ; ; CLEAR MEMORY BOX ; IOCLM: CALL GTONE ; MOVE OURSELVES TO THE CLOSEST PROCESSOR CALL RESET ; SETUP REGISTERS ; ; R4 = CSR ADDRESS FOR THE PORT ACCESSING THE TARGET BOX FROM ; 'THIS' PROCESSOR ; MOV R5,-(SP) ; SAVE UCB ADDRESS MOV (R4),-(SP) ; SAVE STARTING CSR1 VALUE MOV CSR2(R4),R3 ; PICK UP BASE ADDRESS BIT #PROG,R3 ; IS THE BOX PROGRAMMABLE? BEQ 118$ ; BR IF NOT BIC #^C777,R3 ; ISOLATE BASE ADDRESS CMP #77,R3 ; IS THE BOX SET AT INFINITY? BLOS 120$ ; BR IF YES, NOT ACCESSABLE ASH #GRANUL,R3 ; CONVERT TO UNITS OF 32WORDS FROM 32K WORDS. MOV #SIZ,(R4) ; ASK FOR BOX SIZE MOV (R4),R5 ; PICK UP SIZE BIC #100377,R5 ; ISOLATE SIZE FIELD ASL R5 ; CONVERT TO COUNT OF 32 WORD BLOCKS BEQ 118$ ; BR IF SIZE=0 (A MEMORY ERROR CONDITION) ; ; NOW CLEAR ALL CELLS IN THE BOX ; CLR R2 ; SOURCE DATA MOV #ECC,(R4) ; SET BOX TO IGNORE ECC ERRORS 112$: MOV R3,-(SP) ; SAVE BASE ADDRESS MOV R5,-(SP) ; AND SAVE THE BOX SIZE 114$: MOV R3,KISAR6 ; MAP VIA APR6 TO THE NEXT 32WORD UNIT MOV #140000,R1 ; POINT TO THE BLOCK TO CLEAR .REPT 32. MOV R2,(R1)+ ; USE A VECTOR OF MOVE INSTRUCTIONS TO .ENDR ; CLEAR MEMORY INC R3 ; BUMP THE BLOCK POINTER SOB R5,114$ ; LOOP FOR ALL BLOCKS IN THE BOX MOV (SP)+,R5 ; RESTORE SIZE MOV (SP)+,R3 ; AND RESTORE BASE ADDRESS BIT #PROPTR,(R4) ; IS THIS THE SECOND PASS BNE 116$ ; BR IF YES, WERE DONE MOV #PROPTR ! ECC,(R4) ; TOGGLE THE PROTECTION POINTER FOR THE ; SECOND PASS BR 112$ ; AND CLEAR IT AGAIN 116$: MOV (SP)+,(R4) ; RESTORE CSR1 MOV (SP)+,R5 ; RESTORE UCB JMP SUC2 ; WERE DONE! 118$: MOV (SP)+,(R4) ; RESTORE CSR1 MOV (SP)+,R5 ; RESTORE UCB MOV #IE.BAD&377,-(SP) ; PARAMETER ERROR JMP ERROR ; 120$: MOV (SP)+,(R4) ; RESTORE CSR1 MOV (SP)+,R5 ; RESTORE UCB MOV #IE.OFL&377,-(SP) ; MEMORY NOT ACCESSABLE JMP ERROR ; .DSABLE LSB ; ; INTERRUPT ENTRY POINT LABEL FOR LOAD ; MEMORY ERRORS ARE SERVICED BY THE EXECUTIVE ; $MKINT:: RETURN ; THIS IS THE INTERRUPT ENTRY POINT ; THAT WILL NEVER BE USED .PAGE ; ; ; ; ; UTILITY SUBROUTINES AND ENTRY POINTS ; ; ; ; ; ; SUBROUTINE ROUND ; ; THIS ROUTINE IS USED TO STEP THRU ALL OF THE PORTS ASSOCIATED ; WITH THE BOX OF MEMORY CURRENTLY BE ACCESSED. ; THE CURRENT OFFSET INTO THE KTB IS RETAINED IN THE UCB AT ; U.KCTR. THIS POSITION IS CLEARED WHEN ALL KRBS HAVE BEEN ; DELT WITH. ; ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; OUTPUTS: ; THE CARRY BIT INDICATES IF THE DRIVER IS EXECUTING ; ON THE PROPER PROCESSOR. IF THE BIT IS CLEAR THEN ; THE PROPER PROCESSOR HAS CONTROL AND THE ROUTINE ; MAY CONTINUE EXECUTION. IF THE BIT IS SET ; THEN THE CALLER MUST DISMISS HIMSELF AND RETURN FROM ; THE FORK LEVEL ON THE PROPER PROCESSOR. ; ; ROUND: MOV U.SCB(R5),R4 ; GET THE SCB ADDRESS INTO R4 CALL GTKRB ; GET THE NEXT KRB INTO R3 MOV R3,S.KRB(R4) ; MOVE THE TABLE ENTRY INTO THE KRB WORD IN THE ; SCB BEQ 5$ ; IF EQUAL THEN THE ENTRY IN THE KRB TABLE ; IS THE ZERO WORD AT THE END OF THE TABLE ; SO WE ARE FINISHED AND MUST CLEAN UP ; THE COUNTER AND INDICATE SUCCESS TO THE ; CALLER ADD #2,U.KCTR(R5) ; ELSE WE MUST UPDATE THE COUNTER MOV K.URM(R3),S.URM(R4) ; MOVE THE UNIBUS RUN MASK FOR THIS BIT K.URM(R3),$URMST ; IS THE PROCESSOR ONLINE? BEQ ROUND ; IF EQUAL THEN IT IS OFFLINE AND WE ; SKIP THIS PORT BIT #KS.OFL,K.STS(R3) ; ELSE IS THE CONTROLER ONLINE? BEQ 2$ ; IF EQUAL THEN IT IS ONLINE AND WE CONTINUE TST (SP)+ ; ELSE WE HAVE A BAD SITUATION SO ; WE THROW AWAY THE DRIVER CALL MOV #IE.OFL&377,-(SP) ; SET UP THE OFFLINE ERROR BR ERROR ; AND REPORT THE ERROR 2$: MOV (SP)+,R4 ; SAVE THE CALLER INTO R4 CALL $CFORK ; CALL THE CONDITIONAL FORK ROUTINE. ; IF WE ARE EXECUTING ON THE CORRECT PROCESSOR ; THEN WE WILL RETURN HERE AND CONTINUE ; IF NOT THEN WE WILL RETURN TO THE CALLERS ; CALLER AFTER WE ARE ENTERED INTO THE FORK ; QUEUE. WHEN WE ARE DEQUEUED WE SHALL CONTINUE ; FROM HERE.....MAYBE MOV R4,-(SP) ; RESTORE THE CALLER ONTO THE STACK RETURN ; AND RETURN TO HIM. 5$: CLR U.KCTR(R5) ; CLEAR THE COUNTER TO INDICATE THAT ; WE HAVE COMPLETED THE CIRCUIT OF THE ; PORTS. RETURN ; AND RETURN TO THE CALLER ; ; SUBROUTINE RESET ; ; THIS ROUTINE RESETS R4 AND R1 AFTER A RETURN FROM FORK LEVEL ; USING THE UCB ADDRESS IN R5 TO LINK WITH THE CSR ADDRESS IN THE ; KRB AND THE I/O PACKET ADDRESS. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; OUTPUTS: ; R1=ADDRESS OF THE I/O PACKET ; R4=ADDRESS OF THE CSR ; ; RESET: MOV U.SCB(R5),R4 ; GET THE SCB ADDRESS MOV S.PKT(R4),R1 ; GET THE PACKET ADDRESS INTO R1 MOV S.KRB(R4),R4 ; GET THE KRB ADDRESS INTO R4 MOV (R4),R4 ; AND THE CSR INTO R4 RETURN ; RETURN TO CALLER ; ; ; ; SUBROUTINE ERROR ; ; THIS ROUTINE IS THE COMMON ERROR REPORTING PROCESS FOR THIS ; DRIVER. THE COMMUNICATION WITH THE CALLER IS THRU THE IOSB. ; AFTER THE ERROR PARAMETERS ARE SET UP IN R0 AND R1 CONTROL ; IS PASSED TO THE ROUTINE 'SNAP' WHICH LOGS THE PRESENT CONDITION ; OF THE PORTS IN THE DEVICE DEPENDENT BUFFER IN THE UCB. ; THAT ROUTINE CALLS $IODON AND JUMPS TO THE INITIALIZATION ; ENTRY POINT FOR MORE WORK. ; ; ; INPUTS: ; ; (SP)=ERROR CODE ; R4=CSR ADDRESS ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; ; OUTPUTS: ; ; ; R0=ERROR CODE ; ; R1=PORT NUMBER IN HIGH BYTE AND BOX NUMBER IN LOW BYTE ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; ; ERROR: MOV (SP)+,R0 ; GET THE ERROR CODE INTO R0 MOV R0,ECOD1 ; SAVE THE CODE FOR IODON CMP #IE.IFC&377,R0 ; IS IT A BAD PARAMETER OR ; ILLEGAL FUNCTION? BGE 3$ ; IF EQUAL OR GREATER YES AND WE WILL NOT ; REPORT A URM CMP #IE.PRI&377,R0 ; IS IT A PRIVILEDGE VIOLATION? BEQ 3$ ; IF EQUAL THEN YES AND WE RETURN NO URM CALL GTURM ; ELSE WE GET THE CURRENT UNIBUS RUN MASK MOV R3,R1 ; AND SET IT UP TO REPORT THRU THE IOSB 3$: MOVB U.UNIT(R5),ECOD2 ; GET THE UNIT NUMBER INTO THE LOW BYTE OF ; R1 FOR THE $IODON CALL. MOV U.STAD(R5),U.BUF+2(R5) ; GET THE BUFFER STATUS WORD INTO ; BUFFER ADDRESS MOV #IE.ABO&377,-(SP) ; PUT THE FUNCTION STATUS ON THE STACK CALL $PTWRD ; PUT IT INTO THE BUFFER STATUS WORD JMP SNAP ; NOW GO TO THE SNAPSHOT ROUTINE TO LOG THE ; CURRENT STATUS OF THIS BOX. ; ; ; ; ; SUBROUTINE GTONE ; ; ; THIS ROUTINE CONTINUES PROCESSING ON THE PROCESSOR INDICATED ; IN THE USER BUFFER. IF THE PORT REQUESTED IS OUT OF RANGE ; FOR THIS BOX THEN THE CALLER IS CLEARED FROM THE STACK ; AND THE ERROR IS REPORTED THRU THE ROUTINE 'ERROR' ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; THE PORT DESIRED IN THE CURRENT WORD OF THE USER BUFFER ; ; GTONE: CALL $GTWRD ; GET THE DESIRED PORT FROM THE BUFFER CMP #-1,(SP) ; DID THE CALLER SPECIFY A 'WILD CARD' ; PORT NUMBER? BNE 1$ ; BR IF NOT MOV $CPBIT,(SP) ; IF SO SUBSTITUTE THE URM FOR ; THE CURRENT PROCESSOR 1$: CALL GTPRT ; GT THE KRB OF THE PORT IN R4 TST R4 ; IS IT THE END OF THE TABLE? BNE 2$ ; IF NOT EQUAL THEN NO TST (SP)+ ; ELSE WE HAVE AN ERROR CONDITION AND WE ; MUST THROW AWAY THE CALLER MOV #IE.BAD&377,-(SP) ; AND INDICATE THAT WE HAVE A BAD PARAMETER BR ERROR ; AND REPORT SAME. 2$: BIT K.URM(R4),$URMST ; IS THE PROCESSOR ONLINE? BNE 4$ ; IF NOT EQUAL THEN IT IS ONLINE 3$: TST (SP)+ ; ELSE WE HAVE AND ERROR CONDITION AND WE ; MUST THROW AWAY THE CALLER MOV #IE.OFL&377,-(SP) ; ELSE PUSH ERROR CODE ONTO THE STACK BR ERROR ; REPORT THE ERROR 4$: BIT #KS.OFL,K.STS(R4) ; IS THE PORT ONLINE? BNE 3$ ; IF NOT EQUAL THEN IT IS OFFLINE AND WE ; HAVE AN ERROR CONDITION. MOV U.SCB(R5),R3 ; GET THE SCB ADDRESS INTO R3 MOV R4,S.KRB(R3) ; PUT THE KRB ADDRESS INTO THE SCB MOV K.URM(R4),S.URM(R3) ; PUT THE UNIBUS RUN MASK INTO ; THE SCB MOV (SP)+,R4 ; SAVE THE CALLER IN R4 CALL $CFORK ; GET ON THE CORRECT PROCESSOR MOV R4,-(SP) ; RESTORE THE CALLER RETURN ; AND CONTINUE ; ; ; ; ; ; SUBROUTINE GTPRT ; ; ; THIS ROUTINE RETURNS THE KRB ADDRESS THAT IS ON THE UNIBUS ; RUN MASK INDICATED BY THE CURRENT STACK WORD. IF THE MASK IS NOT ; FOUND THEN A ZERO VALUE IS RETURNED. ; ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; ; (SP)=THE UNIBUS RUN MASK ; ; ; OUTPUT ; ; R4=ADDRESS OF THE KRB WITH THE DESIRED MASK ; ; ; GTPRT: CALL GTKRB ; GET THE NEXT KRB INTO R3 TST R3 ; IS IT THE END OF THE TABLE BEQ 3$ ; IF EQUAL THEN YES AND WE USE THE ; ZERO VALUE OF R3 TO INDICATE SAME. CMP 2(SP),K.URM(R3) ; IS THIS THE DESIRED PORT? BEQ 3$ ; IF EQUAL THEN IT IS AND WE RETURN THE ; VALUE. ADD #2,U.KCTR(R5) ; ELSE WE BUMP THE OFFSET COUNTER TO THE ; NEXT ADDRESS BR GTPRT ; AND GO AGAIN 3$: MOV R3,R4 ; GET IT INTO THE REPORTING REGISTER MOV (SP),2(SP) ; GET THE CALLER INTO THE SECOND SLOT TST (SP)+ ; CLEAN THE STACK CLR U.KCTR(R5) ; ZERO THE COUNTER RETURN ; AND GO BACK ; ; ; ; ; ; SUBROUTINE GTKRB ; ; ; THIS ROUTINE RETURNS THE ADDRESS OF THE KRB POINTED TO BY THE ; OFFEST COUNTER AT U.KCTR(R5) IN R3. ; ; ; INPUTS: ; ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; ; U.KCTR(R5)=OFFSET TO DESIRED KRB IN THE S.KTB TABLE. ; ; GTKRB: MOV U.KCTR(R5),R3 ; GET THE OFFSET INTO R3 ADD U.SCB(R5),R3 ; ADD IN THE SCB ADDRESS MOV S.KTB(R3),R3 ; GET THE ADDRESS OF THE KRB INTO ; R3 RETURN ; GO BACK ; ; ; ; ; ; ; ; ; SUBROUTINE STATUS ; ; ; THIS ROUTINE WILL PUT THE SECOND WORD ON THE STACK INTO THE ; STATUS WORD OF THE USER BUFFER. ; ; ; INPUTS: ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; 2(SP)=ERROR CODE ; ; ; STATUS: MOV U.BUF+2(R5),-(SP) ; PUT THE CURRENT BUFFER ADDRESS ON THE ; STACK MOV U.STAD(R5),U.BUF+2(R5) ; MOVE THE STATUS WORD ADDRESS INTO THE ; BUFFER SLOT MOV 4(SP),-(SP) ; PUT THE ERROR CODE ONTO THE STACK CALL $PTWRD ; PUT THE ERROR CODE INTO THE BUFFER MOV (SP)+,U.BUF+2(R5) ; RESTORE THE BUFFER ADDRESS MOV (SP)+,(SP) ; AND CLEAN UP THE STACK RETURN ; GO BACK ; ; ; SUBROUTINE SUC ; ; THIS ROUTINE HANDLES A SUCCESSFULL COMPLETION OF A FUNCTION. ; ; SUCCESS IS INDICATED IN THE IOSB AND THE BUFFER STATUS WORD ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; SUC: MOV #IS.SUC,ECOD1 ; SET UP SUCCESS IN FOR THE IOSB CLR ECOD2 ; ZERO THE 2ND IOSB WORD ; ; ; ; SUBROUTINE SNAP ; ; THIS ROUTINE IS USED TO GET A 'SNAPSHOT' OF THE MEMORY CSRS STORED ; IN WORDS U.CSAV TO U.CSAV+2. THESE WORDS ARE USED AFTER A REAL ; POWERFAIL TO RESET THE MEMORY TO IT'S PREVIOUS CONDITION. ; THIS ROUTINE IS ENTERED FROM BOTH ERROR AND SUCCESS CONDITIONS. ; ; ; INPUTS: ; ; R0= DATA FOR THE FIRST WORD OF THE I/O STATUS BLOCK ; ; R1= DATA FOR THE SECOND WORD OF THE I/0 STATUS BLOCK ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; SNAP: CALL SNAP1 ; GET ALL OF THE CSRS COPIED INTO THE ; U.CSAV AREA SUC2: CLR U.PWRV(R5) ; CLEAR THE POWERFAIL RECOVERY VECTOR MOV ECOD1,R0 ; FIRST IOSB WORD MOV ECOD2,R1 ; SECOND IOSB WORD CALL $IODON ; CLEAN UP THE FUNCTION MOV U.SCB(R5),R0 ; GET SCB ADDRESS CLR S.KRB(R0) ; CLEAR KRB ADDRESS CLR S.URM(R0) ; AND REQUIRED UNIBUS RUN MASK JMP MKINI ; GO GET THE NEXT PACKET ; ; ; ; ; SUBROUTINE SNAP1 ; ; ; THIS ROUTINE IS USED TO GET AN IMAGE OF THE CSRS THAT ARE ; CURRENTLY ONLINE INTO THE IMAGE STORAGE BUFFER THAT STARTS ; AT U.CSAV IN THE UCB. ; ; ; INPUTS: ; ; ; R5=ADDRESS OF THE UCB OF THE UNIT CURRENTLY BEING ACCESSED ; ; ; OUTPUT: ; ; ; CSR IMAGES ARE IN THE STORAGE BUFFER ; ; ; ; .ENABLE LSB 5$: ADD #2,U.KCTR(R5) ; ADVANCE TO NEXT PORT SNAP1: CALL GTKRB ; GET A KRB ADDRESS IN R3 BEQ 10$ BIT K.URM(R3),$URMST ; IS THIS CPU ONLINE? BEQ 5$ ; BR IF NOT. TRY NEXT PORT MOV U.SCB(R5),R4 ; ENSURE WE HAVE THE SCB MOV R3,S.KRB(R4) ; SET THE SCB MOV K.URM(R3),S.URM(R4) ; SET THE MASK FOR THE CONTROLLER MOV (SP)+,R4 ; GET RETURN ADDRESS TO CALLER CALL $IFORK ; GO TO A PROCESSOR MOV R4,-(SP) ; SAVE RETURN ADDRESS TO CALLER CALL GTKRB ; AND REFRESH THE REGISTERS MOV (R3),R3 ; OBTAIN CSR ADDRESS. SINCE "ALL" ; ACCESSABLE REGISTERS HAVE BEEN ; SET THE SAME BY OUR CALLER, PCIK ; ANY KRB TO GET THE CSR ADDRES. MOV CSR1(R3),U.CSAV(R5) ; SAVE THE MEMORY CONTROLLER REGISTERS MOV CSR2(R3),U.CSAV+2(R5) ; AGAINS A POWER FAIL CLR U.KCTR(R5) ; CLEAN UP FROM GTKRB 10$: RETURN ; .DSABLE LSB ; ; ; ; ; ; SUBROUTINE GTURM ; ; THIS ROUTINE PUTS THE UNIBUS RUN MASK FOR THE CURRENT ; PORT INTO THE HIGH BYTE OF R3. ; ; ; INPUTS: ; ; R4=KRB ADDRESS ; ; ; OUTPUT: ; ; R3=UNIBUS RUN MASK FOR PORT IN HIGH BYTE ; ; GTURM: MOV U.SCB(R5),R4 MOV S.KRB(R4),R4 MOV K.URM(R4),R3 ; GET THE UNIBUS RUN MASK INTO THE LOW BYTE SWAB R3 ; MOVE THE MASK INTO THE HIGH BYTE RETURN ; ; .PAGE ; ; ; MKPWF: MKOUT: MKCAN: RETURN ; THESE TWO POINTS SHOULD NEVER BE USED ; ON THIS DRIVER BUT JUST IN CASE. ; ; THESE ARE THE ENTRY POINTS FOR THE ONLINE AND OFFLINE ; STATUS CHANGES. ; ; .ENABLE LSB ; MKKRB: BCS 30$ ; BR IF OFFLINE REQUEST ; OFFLINE IS CONSIDERED ALWAYS ; SUCCESSFUL. *** CAUTION *** ; THIS ASSUMPTION IS MADE SO THAT ; A UNIT CAN GO OFFLINE WHEN A ; CPU GOES OFFLINE. HRC MUST CHECK ; TO INSURE THAT OFFL COMMANDS MAY ; NEVER GET HERE WITH THE BOX ; MEMORY ON-LINE. ; ; CONTROLLER ONLINE SERVICE ; MOV K.OWN(R2),R1 ; PICK UP OWNING UCB BEQ 25$ ; BR IF NONE MOVB U.UNIT(R1),R1 ; GET BOX UNIT NUMBER ASL R1 ; CONVERT TO WORD INDEX CMP #160000,$MKCSR(R1) ; IS THE EXECUTIVE TABLE ENTRY DUMMY? BLO 30$ ; NO, SKIP CSR MODIFICATION MOV K.CSR(R2),R1 ; PICK UP CSR ADDRESS MOV #BAS1,(R1) ; MOVE BOX TO INFINITY MOV #BAS2,CSR2(R1) ; LOAD ADDRESS AND CONTROL BR 30$ ; RETURN TO EXECUTIVE ; ; UNIT ONLINE/OFFLINE SERVICE ; MKUCB: BCC 30$ ; NOP IF UNIT ONLINE REQUEST ; UNIT OFFLINE SERVICE ; MOV R5,R1 ; COPY UCB ADDRESS BR 15$ ; TO COMMON CODE 10$: MOV K.OWN(R2),R1 ; GET UCB BEQ 25$ ; BR IF NO UCB 15$: MOVB U.UNIT(R1),R1 ; PICK UP BOX NUMBER ASL R1 ; CONVERT TO WORD OFFSET CMP #160000,$MKCSR(R1) ; IS BOX ADDRESS DUMMY? BHI 30$ ; BR IF YES, OFFLINE MAY PROCEED 25$: MOVB #IE.ONL,$SCERR ; OTHERWISE MARK STATUS CHANGE ERROR 30$: RETURN ; TO EXEC .DSABLE LSB .END